package com.ciaojian.worker.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ciaojian.core.bytedance.*;
import com.ciaojian.core.bytedance.api.ByteDanceRequestApi;
import com.ciaojian.core.bytedance.auth.ByteDanceTokenProvider;
import com.ciaojian.core.bytedance.vo.ByteMiniAccessToken;
import com.ciaojian.core.bytedance.vo.SubscrbeVo;
import com.ciaojian.core.constant.RedisConstant;
import com.ciaojian.core.model.Order;
import com.ciaojian.core.util.JsonUtil;
import com.ciaojian.core.util.LogUtil;
import com.ciaojian.core.util.RedisUtil;
import com.ciaojian.core.util.Result;
import com.ciaojian.miniapp.api.WxMiniAppApi;
import com.ciaojian.miniapp.model.request.submessage.*;
import com.ciaojian.miniapp.model.response.SubMessageSendResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;


/**
 * @author Atlakyn
 */
@Service
public class SubMessageServiceImpl {
    @Resource
    private UserServiceImpl userService;
    @Resource
    private ByteDanceTokenProvider byteDanceTokenProvider;

    /**
     * 提现用户支付
     *
     * @param order 订单
     * @throws JsonProcessingException json 转换异常
     */
    public Result remindUserPayment(Order order) throws IOException {

        if (order.getChannel()==1) {
            // 用户的 openid
            String openId = userService.getOpenIdById(order.getUserId());
            BaseTemplate baseTemplate = BaseTemplate.builder(TemplateIdEnum.REMIND_PAYMENT)
                    .touser(openId)
                    .data(RemindUserPayMessage.builder()
                            .thing1(order.getType())
                            .name2(order.getWorkerName())
                            .amount3(order.getGoodsTotal())
                            .character_string4(order.getOrderNo())
                            .thing6("订单未支付")
                            .build()
                    );
            SubMessageSendResponse response = WxMiniAppApi.subscribeMessageSend(baseTemplate);
            RedisUtil.setKeyTime(RedisConstant.REMIND_USER_PAYMENT + order.getUserId(), 600, "0");
            if (response.getErrcode() == 0) {
                return Result.ok("提醒成功");
            } else {
                LogUtil.writeBusinessLog("发型师提醒用户付款失败,微信返回信息: {}", response.getErrmsg());
                return Result.error(response.getErrcode(), "提醒失败");
            }
        }

        if (order.getChannel()==2){

            JSONObject param1 = new JSONObject();
            param1.put("appid", ByteDanceMiniConfig.APP_ID);
            param1.put("secret", ByteDanceMiniConfig.SECRET_ID);
            param1.put("grant_type", "client_credential");
            //定义接收数据
            JSONObject result = new JSONObject();

            String access_token_v2 = ByteDanceRequestApi.sendRequest(MiniAppRequestApi.ACCESS_TOKEN_V2, param1);

            result = JSON.parseObject(access_token_v2);
            ByteMiniAccessToken byteMiniAccessToken = result.toJavaObject(ByteMiniAccessToken.class);


            String openId = userService.getBaseMapper().getDyOpenIdById(order.getUserId());
//            String bytedance_clienttoken = byteDanceTokenProvider.getBytedanceClienttoken("BYTEDANCE_MINIAPP_ACCESSTOKEN");

//            SubscrbeVo subscrbeVo = new SubscrbeVo();
//            subscrbeVo.set发型师(order.getWorkerName());

            JSONObject param = new JSONObject();
            param.put("access_token", byteMiniAccessToken.getData().getAccess_token());
            param.put("app_id", ByteDanceMiniConfig.APP_ID);
            param.put("tpl_id", ByteDanceMiniConfig.PAY_INFORM);
            param.put("open_id", openId);
            String jsonStr = "{ \"服务名称\": \"" + order.getType() + "\", " +
                    "\"发型师名称\": \"" + order.getWorkerName() + "\"," +
                    "\"金额\": \""+order.getGoodsTotal()+"\"," +
                    "\"订单号\": \"" + order.getOrderNo() + "\"," +
                    "\"温馨提示\": \"订单未支付\" }";
            param.put("data",  JsonUtil.json2Map(jsonStr));

            //定义接收数据
            HttpResponse response = DySubscribeApi.subscribeMessageSend(param, ByteDanceMiniConfig.SUBSCRIBE_NOTIFICATION, "/api/apps/subscribe_notification/developer/v1/notify");

            if (response.getStatusLine().getStatusCode() == 200) {
                result = JSON.parseObject(EntityUtils.toString(response.getEntity(), "UTF-8"));
                RedisUtil.setKeyTime(RedisConstant.CALL_USER + order.getId(), 600, "0");
                return Result.ok("提醒成功");
            }else {
                LogUtil.writeBusinessErrorLog("发型师提醒用户排队失败,抖音返回信息: {}", JSON.parseObject(EntityUtils.toString(response.getEntity(), "UTF-8")));
                return Result.error("提醒失败");
            }
        }



        return null;
    }

    /**
     * 叫号
     *
     * @param order 订单
     * @return 通知返回结果
     * @throws JsonProcessingException json 转换异常
     */
    public Result callUser(Order order) throws IOException {
        if (order.getChannel()==1) {
            // 用户的 openid
            String openId = userService.getOpenIdById(order.getUserId());
            BaseTemplate baseTemplate = BaseTemplate.builder(TemplateIdEnum.REMIND_RANK)
                    .touser(openId)
                    .data(QueueMessage.builder()
                            .name2(order.getWorkerName())
                            .thing3(order.getStoreName())
                            .thing5("15分钟内")
                            .thing6("已经到你啦")
                            .character_string9(order.getRankNo())
                            .build()
                    );
            SubMessageSendResponse response = WxMiniAppApi.subscribeMessageSend(baseTemplate);
            RedisUtil.setKeyTime(RedisConstant.CALL_USER + order.getId(), 600, "0");
            if (response.getErrcode() == 0) {
                return Result.ok("提醒成功");
            } else {
                LogUtil.writeBusinessLog("发型师提醒用户付款失败,微信返回信息: {}", response.getErrmsg());
                return Result.error(response.getErrcode(), "提醒失败");
            }
        }

        if (order.getChannel()==2){

            JSONObject param1 = new JSONObject();
            param1.put("appid", ByteDanceMiniConfig.APP_ID);
            param1.put("secret", ByteDanceMiniConfig.SECRET_ID);
            param1.put("grant_type", "client_credential");
            //定义接收数据
            JSONObject result = new JSONObject();

            String access_token_v2 = ByteDanceRequestApi.sendRequest(MiniAppRequestApi.ACCESS_TOKEN_V2, param1);

            result = JSON.parseObject(access_token_v2);
            ByteMiniAccessToken byteMiniAccessToken = result.toJavaObject(ByteMiniAccessToken.class);


            String openId = userService.getBaseMapper().getDyOpenIdById(order.getUserId());
//            String bytedance_clienttoken = byteDanceTokenProvider.getBytedanceClienttoken("BYTEDANCE_MINIAPP_ACCESSTOKEN");

//            SubscrbeVo subscrbeVo = new SubscrbeVo();
//            subscrbeVo.set发型师(order.getWorkerName());

            JSONObject param = new JSONObject();
            param.put("access_token", byteMiniAccessToken.getData().getAccess_token());
            param.put("app_id", ByteDanceMiniConfig.APP_ID);
            param.put("tpl_id", ByteDanceMiniConfig.QUEUE_INFORM);
            param.put("open_id", openId);
            String jsonStr = "{ \"门店\": \"" + order.getStoreName() + "\", " +
                    "\"排队号\": \"" + order.getRankNo() + "\"," +
                    "\"等待时间\": \"15分钟内\"," +
                    "\"发型师\": \"" + order.getWorkerName() + "\"," +
                    "\"温馨提示\": \"已经到你啦\" }";
            param.put("data",  JsonUtil.json2Map(jsonStr));

            //定义接收数据
            HttpResponse response = DySubscribeApi.subscribeMessageSend(param, ByteDanceMiniConfig.SUBSCRIBE_NOTIFICATION, "/api/apps/subscribe_notification/developer/v1/notify");

            if (response.getStatusLine().getStatusCode() == 200) {
                result = JSON.parseObject(EntityUtils.toString(response.getEntity(), "UTF-8"));
                RedisUtil.setKeyTime(RedisConstant.CALL_USER + order.getId(), 600, "0");
                return Result.ok("提醒成功");
            }else {
                LogUtil.writeBusinessErrorLog("发型师提醒用户排队失败,抖音返回信息: {}", JSON.parseObject(EntityUtils.toString(response.getEntity(), "UTF-8")));
                return Result.error("提醒失败");
            }
        }

        return null;

    }

    /**
     * 排队提醒
     *
     * @param order1 第一个排队订单
     * @param order2 第二个排队订单
     * @throws JsonProcessingException JSON 转换异常
     */
    public void remindRank(Order order1, Order order2) throws IOException {
        if (order1 != null) {

            //微信通知
            if (order1.getChannel()==1) {
                LogUtil.writeBusinessLog("remindRank>发型师发送叫号推送消息;被叫人={}", order1.getUserId());
                String openId = userService.getBaseMapper().getOpenIdById(order1.getUserId());
                // 给下一个排队的人发送消息
                // 构建推送内容
                BaseTemplate baseTemplate = BaseTemplate.builder(TemplateIdEnum.REMIND_RANK)
                        .touser(openId)
                        .data(QueueMessage.builder()
                                .name2(order1.getWorkerName())
                                .thing3(order1.getStoreName())
                                .thing5("前面等待0人，预计等待0分钟")
                                .thing6("请尽快到店")
                                .character_string9(order1.getRankNo())
                                .build()
                        );
                SubMessageSendResponse response = WxMiniAppApi.subscribeMessageSend(baseTemplate);
                if (response.getErrcode() == 0) {
                } else {
                    LogUtil.writeBusinessErrorLog("发型师提醒用户付款失败,微信返回信息: {}", response.getErrmsg());
                }
            }

            //抖音通知
            if (order1.getChannel()==2) {
                LogUtil.writeBusinessLog("remindRank>发型师发送叫号推送消息;被叫人={}", order1.getUserId());
                JSONObject param1 = new JSONObject();
                param1.put("appid", ByteDanceMiniConfig.APP_ID);
                param1.put("secret", ByteDanceMiniConfig.SECRET_ID);
                param1.put("grant_type", "client_credential");
                //定义接收数据
                JSONObject result = new JSONObject();

                String access_token_v2 = ByteDanceRequestApi.sendRequest(MiniAppRequestApi.ACCESS_TOKEN_V2, param1);

                result = JSON.parseObject(access_token_v2);
                ByteMiniAccessToken byteMiniAccessToken = result.toJavaObject(ByteMiniAccessToken.class);


                String openId = userService.getBaseMapper().getDyOpenIdById(order1.getUserId());
//            String bytedance_clienttoken = byteDanceTokenProvider.getBytedanceClienttoken("BYTEDANCE_MINIAPP_ACCESSTOKEN");

//            SubscrbeVo subscrbeVo = new SubscrbeVo();
//            subscrbeVo.set发型师(order.getWorkerName());

                JSONObject param = new JSONObject();
                param.put("access_token", byteMiniAccessToken.getData().getAccess_token());
                param.put("app_id", ByteDanceMiniConfig.APP_ID);
                param.put("tpl_id", ByteDanceMiniConfig.QUEUE_INFORM);
                param.put("open_id", openId);
                String jsonStr = "{ \"门店\": \"" + order1.getStoreName() + "\", " +
                        "\"排队号\": \"" + order1.getRankNo() + "\"," +
                        "\"等待时间\": \"15分钟内\"," +
                        "\"发型师\": \"" + order1.getWorkerName() + "\"," +
                        "\"温馨提示\": \"已经到你啦\" }";
                param.put("data",  JsonUtil.json2Map(jsonStr));

                //定义接收数据
                HttpResponse response = DySubscribeApi.subscribeMessageSend(param, ByteDanceMiniConfig.SUBSCRIBE_NOTIFICATION, "/api/apps/subscribe_notification/developer/v1/notify");

                if (response.getStatusLine().getStatusCode() == 200) {
                    param = JSON.parseObject(EntityUtils.toString(response.getEntity(), "UTF-8"));
                }else {
                    LogUtil.writeBusinessErrorLog("发型师提醒用户排队失败,抖音返回信息: {}", JSON.parseObject(EntityUtils.toString(response.getEntity(), "UTF-8")));
                }
            }
        }
        if (order2 != null) {

            //微信通知
            if (order2.getChannel()==1) {
                LogUtil.writeBusinessLog("remindRank>发型师发送叫号推送消息;被叫人={}", order2.getUserId());
                String openId1 = userService.getBaseMapper().getOpenIdById(order2.getUserId());
                BaseTemplate baseTemplate1 = BaseTemplate.builder(TemplateIdEnum.REMIND_RANK)
                        .touser(openId1)
                        .data(QueueMessage.builder()
                                .thing3(order2.getStoreName())
                                .character_string9(order2.getRankNo())
                                .thing5("前面等待1人，预计等待15分钟")
                                .name2(order2.getWorkerName())
                                .thing6("请尽快到店")
                                .build()
                        );
                SubMessageSendResponse response = WxMiniAppApi.subscribeMessageSend(baseTemplate1);
                if (response.getErrcode() == 0) {
                } else {
                    LogUtil.writeBusinessErrorLog("- 发型师提醒用户付款失败,微信返回信息: {}", response.getErrmsg());
                }
            }

            //抖音通知
            if (order2.getChannel()==2){
                LogUtil.writeBusinessLog("remindRank>发型师发送叫号推送消息;被叫人={}", order2.getUserId());
                JSONObject param1 = new JSONObject();
                param1.put("appid", ByteDanceMiniConfig.APP_ID);
                param1.put("secret", ByteDanceMiniConfig.SECRET_ID);
                param1.put("grant_type", "client_credential");
                //定义接收数据
                JSONObject result = new JSONObject();

                String access_token_v2 = ByteDanceRequestApi.sendRequest(MiniAppRequestApi.ACCESS_TOKEN_V2, param1);

                result = JSON.parseObject(access_token_v2);
                ByteMiniAccessToken byteMiniAccessToken = result.toJavaObject(ByteMiniAccessToken.class);


                String openId = userService.getBaseMapper().getDyOpenIdById(order1.getUserId());


                JSONObject param = new JSONObject();
                param.put("access_token", byteMiniAccessToken.getData().getAccess_token());
                param.put("app_id", ByteDanceMiniConfig.APP_ID);
                param.put("tpl_id", ByteDanceMiniConfig.QUEUE_INFORM);
                param.put("open_id", openId);
                String jsonStr = "{ \"门店\": \"" + order2.getStoreName() + "\", " +
                        "\"排队号\": \"" + order2.getRankNo() + "\"," +
                        "\"等待时间\": \"15分钟内\"," +
                        "\"发型师\": \"" + order2.getWorkerName() + "\"," +
                        "\"温馨提示\": \"已经到你啦\" }";
                param.put("data",  JsonUtil.json2Map(jsonStr));

                //定义接收数据
                HttpResponse response = DySubscribeApi.subscribeMessageSend(param, ByteDanceMiniConfig.SUBSCRIBE_NOTIFICATION, "/api/apps/subscribe_notification/developer/v1/notify");

                if (response.getStatusLine().getStatusCode() == 200) {
                    param = JSON.parseObject(EntityUtils.toString(response.getEntity(), "UTF-8"));
                }else {
                    LogUtil.writeBusinessErrorLog("发型师提醒用户排队失败,抖音返回信息: {}", JSON.parseObject(EntityUtils.toString(response.getEntity(), "UTF-8")));
                }
            }
        }
    }
}